
package com.hlkj.pay.service.order.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.time.format.DateTimeFormatter;
import java.util.List;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.pojo.PageResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.hlkj.pay.app.merchant.ext.impl.wxpay.dto.WxRiskNotifyResp;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.dto.order.RiskOrderQueryDto;
import com.hlkj.pay.infrastructure.mapper.order.OrderRiskMapper;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessAuthDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.order.OrderComplaintChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderRiskDO;
import com.hlkj.pay.service.CommonSnFilterService;
import com.hlkj.pay.service.merchant.IMerchantAccessAuthService;
import com.hlkj.pay.service.merchant.IMerchantAccessService;
import com.hlkj.pay.service.order.IOrderComplaintChannelService;
import com.hlkj.pay.service.order.IOrderRiskService;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.vo.order.req.ComplaintDeleteReq;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/11/07 10:46
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderRiskServiceImpl extends CommonSnFilterService implements IOrderRiskService {

    private final OrderRiskMapper orderRiskMapper;

    private final IMerchantAccessAuthService merchantAccessAuthService;

    private final IOrderComplaintChannelService orderComplaintChannelService;

    private final IMerchantAccessService merchantAccessService;


    @Override
    public CommonResult<Void> addOrderRisk(OrderRiskDO OrderRiskDO) {
        orderRiskMapper.insert(OrderRiskDO);
        return CommonResult.success();
    }

    @Override
    public PageResult<OrderRiskDO> queryPage(RiskOrderQueryDto riskOrderQueryDto) {
        LambdaQueryWrapper<OrderRiskDO> queryWrapper = buildWrapper(riskOrderQueryDto);
        return orderRiskMapper.selectPage(riskOrderQueryDto,queryWrapper);
    }

    @Override
    public List<OrderRiskDO> queryList(RiskOrderQueryDto riskOrderQueryDto) {
        LambdaQueryWrapper<OrderRiskDO> queryWrapper = buildWrapper(riskOrderQueryDto);
        List<OrderRiskDO> list = orderRiskMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public OrderRiskDO queryDetail(Long id) {
        OrderRiskDO orderRiskDO = orderRiskMapper.selectById(id);
        if(orderRiskDO.getChannelId() != null){
            OrderComplaintChannelDO channelDO = orderComplaintChannelService.queryDetail(orderRiskDO.getChannelId());
            if(channelDO != null){
                orderRiskDO.setChannelSubject(channelDO.getSubject());
            }
        }
        return orderRiskDO;
    }

    @Override
    public CommonResult<Void> delBatch(ComplaintDeleteReq complaintDeleteReq) {
        if(CollUtil.isNotEmpty(complaintDeleteReq.getId())){
            orderRiskMapper.deleteBatchIds(complaintDeleteReq.getId());
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<Void> updateOrderRisk(OrderRiskDO OrderRiskDO) {
        try {
            if (OrderRiskDO.getId() == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            OrderRiskDO orderRiskDO = queryDetail(OrderRiskDO.getId());
            if (orderRiskDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderRiskMapper.updateById(OrderRiskDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updateOrderRisk error:{}",  e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delOrderRisk(Long id) {
        try {
            if (id == null) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            OrderRiskDO orderRiskDO = queryDetail(id);
            if (orderRiskDO == null) {
                return CommonResult.error(CommonResultCode.DATA_NOT_EXIST);
            }
            orderRiskMapper.deleteById(id);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delOrderRisk error:{}", e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public OrderRiskDO selectOne(RiskOrderQueryDto riskOrderQueryDto) {
        return orderRiskMapper.selectOne(buildWrapper(riskOrderQueryDto));
    }

    @Override
    public CommonResult<Void> test(WxRiskNotifyResp notifyResp) {

        // 获取风险通道配置
        OrderComplaintChannelDO orderComplaintChannelDO = orderComplaintChannelService.queryDetail(notifyResp.getId());

        OrderRiskDO updateOrderRiskDO = new OrderRiskDO();
        updateOrderRiskDO.setChannelId(notifyResp.getId());
        updateOrderRiskDO.setRiskId(notifyResp.getRecord_id());
        updateOrderRiskDO.setRiskType(notifyResp.getRisk_type());
        updateOrderRiskDO.setRiskDescription(notifyResp.getRisk_description());
        updateOrderRiskDO.setAppId(orderComplaintChannelDO.getMchid());
        updateOrderRiskDO.setCompanyName(notifyResp.getCompany_name());
        updateOrderRiskDO.setPunishPlan(notifyResp.getPunish_plan());
        updateOrderRiskDO.setPunishDescription(notifyResp.getPunish_description());
        updateOrderRiskDO.setSubMchid(notifyResp.getSub_mchid());
        updateOrderRiskDO.setType(orderComplaintChannelDO.getType());

        if(StrUtil.isNotEmpty(notifyResp.getPunish_time())){
            updateOrderRiskDO.setPunishTime(DateUtils.shanghaiDate(notifyResp.getPunish_time(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
        }

        // 通过sub_mchid查询报备信息
        MerchantAccessAuthDO authDO = new MerchantAccessAuthDO();
        authDO.setSubMchId(notifyResp.getSub_mchid());
        MerchantAccessAuthDO merchantAccessAuthDO =  merchantAccessAuthService.queryMerchantAccessAuth(authDO);
        if(merchantAccessAuthDO == null){
            log.error("riskCallBack 未查询到报备商户号:{}", JsonUtils.toJsonString(notifyResp));
        }else{
            updateOrderRiskDO.setSn(merchantAccessAuthDO.getSn());
            updateOrderRiskDO.setAccessId(merchantAccessAuthDO.getAccessId());

            // 查询进件信息
            MerchantAccessInfoDO merchantAccessInfoDO = merchantAccessService.detail(merchantAccessAuthDO.getAccessId());
            if(merchantAccessInfoDO != null){
                updateOrderRiskDO.setProviderCode(merchantAccessInfoDO.getProviderCode());
                updateOrderRiskDO.setChannelCode(merchantAccessInfoDO.getChannelCode());
            }
        }

        // 查询数据库
        RiskOrderQueryDto riskOrderQueryDto = new RiskOrderQueryDto();
        riskOrderQueryDto.setRiskId(notifyResp.getRecord_id());
        OrderRiskDO orderRiskDO = selectOne(riskOrderQueryDto);
        // 数据库已有记录
        if(orderRiskDO != null){
            updateOrderRiskDO.setId(orderRiskDO.getId());
            updateOrderRisk(updateOrderRiskDO);
            log.info("riskCallBack update:{}", JsonUtils.toJsonString(updateOrderRiskDO));
        }else{
            addOrderRisk(updateOrderRiskDO);
            log.info("riskCallBack add:{}", JsonUtils.toJsonString(updateOrderRiskDO));
        }
        return CommonResult.success();
    }
    /**
     * 查询条件封装
     * @param riskOrderQueryDto
     * @return
     */
    LambdaQueryWrapper<OrderRiskDO> buildWrapper(RiskOrderQueryDto riskOrderQueryDto) {
        filterSn(riskOrderQueryDto);
        LambdaQueryWrapperX<OrderRiskDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(OrderRiskDO::getId, riskOrderQueryDto.getId());
        queryWrapper.eqIfPresent(OrderRiskDO::getRiskId, riskOrderQueryDto.getRiskId());
        queryWrapper.eqIfPresent(OrderRiskDO::getSubMchid, riskOrderQueryDto.getSubMchid());
        queryWrapper.eqIfPresent(OrderRiskDO::getType, riskOrderQueryDto.getType());
        queryWrapper.eqIfPresent(OrderRiskDO::getChannelCode, riskOrderQueryDto.getChannelCode());
        queryWrapper.eqIfPresent(OrderRiskDO::getProviderCode, riskOrderQueryDto.getProviderCode());
        queryWrapper.likeIfPresent(OrderRiskDO::getCompanyName, riskOrderQueryDto.getCompanyName());
        queryWrapper.eqIfPresent(OrderRiskDO::getSn, riskOrderQueryDto.getSn());
        queryWrapper.eqIfPresent(OrderRiskDO::getAppId, riskOrderQueryDto.getAppId());
        queryWrapper.geIfPresent(OrderRiskDO::getCreateTime, riskOrderQueryDto.getStartQueryTime());
        queryWrapper.leIfPresent(OrderRiskDO::getCreateTime, riskOrderQueryDto.getEndQueryTime());
        return queryWrapper;
    }
}
